package com.szh.easyexcel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.szh.easyexcel.dto.ProductExcelDto;
import com.szh.easyexcel.model.Product;
import com.szh.easyexcel.service.ProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 针对Excel的读，我们需要写一个监听器，去不断的监听读取Excel的每一行数据，最终加入数据库类似这样的操作
 * 有个很重要的点 DemoDataListener 不能被spring管理，每次读取excel都要new，然后里面用到spring可以构造方法传进去
 * 这也就是监听器中需要声明 private GoodsService goodsService; 这个成员变量的原因
 *
 * @author: SongZiHao
 * @date: 2023/5/27
 */
public class ProductExcelListener implements ReadListener<ProductExcelDto> {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProductExcelListener.class);
    private ProductService productService;
    private List<ProductExcelDto> productExcelDtoList = ListUtils.newArrayList();
    private List<Product> productList = new ArrayList<>();
    private int count = 0;

    public ProductExcelListener() {
    }

    public ProductExcelListener(ProductService productService) {
        this.productService = productService;
    }

    /**
     * 针对Excel表头的一些操作
     */
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        Map<Integer, String> excelHeadMap = ConverterUtils.convertToStringMap(headMap, context);
        LOGGER.info("该Excel的表头信息是 ===> ");
        Set<Map.Entry<Integer, String>> entrySet = excelHeadMap.entrySet();
        for (Map.Entry<Integer, String> entry : entrySet) {
            LOGGER.info("第 {} 列是 ===> {}", entry.getKey() + 1, entry.getValue());
        }
    }

    /**
     * 解析Excel中的每一条数据都会来调用它
     */
    @Override
    public void invoke(ProductExcelDto data, AnalysisContext context) {
        LOGGER.info("解析到第 {} 条数据 ===> {}", (++count), JSON.toJSONString(data));
        productExcelDtoList.add(data);
    }

    /**
     * 所有数据解析完成了会来调用它
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        LOGGER.info("该Excel的所有数据解析完毕！！！");
        LOGGER.info("productExcelDtoList ===> {}", JSON.toJSONString(productExcelDtoList));
        for (ProductExcelDto productExcelDto : productExcelDtoList) {
            try {
                Product product = new Product();
                product.setId(productExcelDto.getId());
                product.setName(productExcelDto.getName());
                product.setInfo(productExcelDto.getInfo());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                product.setBuyTime(sdf.parse(productExcelDto.getBuyTime()));
                product.setCreateTime(new Date());
                productList.add(product);
            } catch (ParseException ex) {
                LOGGER.error("日期解析异常 ===> {}", ex.getMessage());
            }
        }
        productExcelDtoList = ListUtils.newArrayList();
        LOGGER.info("productList ===> {}", JSON.toJSONString(productList));
        productService.insertBatch(productList);
    }
}
